In this lecture, we're going to take a closer look at how to manipulate physics in Roblox Studio by
manipulating the assembly linear velocity property of parts, as well as using a couple constraints.
One is called vector force and the other is called linear velocity.
Before we get started, we should first differentiate between these three things and when you would
want to use them.
If you need to apply a one time initial force on an object, then this is where you would use the assembly
linear velocity property or use a function on base parts called apply impulse to apply a one time force
onto your object.
This of course, will take into account the different properties for your objects, such as the mass
of the object and any type of friction acting upon your object.
And if you need to apply a constant force instead of a one time force on your object, then instead
you would use something called a vector force instance, which will constantly apply a force over and
over on your object.
And since this constantly applies a force, these forces can build up over time, which could result
in very high speeds on your object if you don't have any other forces acting on it.
And then lastly, if you need to have a constant velocity on your object instead of a constant force,
then you would use a linear velocity instance, and this will have your part constantly move at a consistent
velocity, regardless of its mass or its size.
So let's go ahead and first take a look at assembly linear velocity and using a function called apply
impulse on parts.
Every single part in your game is going to have an assembly linear velocity.
And they're also going to have a function to apply an impulse on that part.
Now we can set the assembly linear velocity of a part directly through the property menu.
So no matter what the mass of our object is, if we were to update the value of the assembly linear
velocity to ten, then that's going to be the force applied.
So my mass is currently at 44.8.
And then if I hit enter here, as you can see my part jumped a little bit.
But if I were to decrease the mass, let me enable custom physical properties and set the density all
the way to 0.01.
I'm going to have a very tiny little mass, and you would think that me applying this same force would
mean that my part would jump up higher.
But you're going to be wrong.
It still only jumps the same amount, and that's because we're keeping the assembly linear velocity
the same.
The previous one had an assembly linear velocity of ten or positive ten force in the y axis.
And so also was the force that we applied on this part with a smaller mass.
So the assembly linear velocity is a property that represents the movement of our part in how many studs
per second.
So basically you could think of me applying a force of ten means my part would move ten studs per second
positive in the y axis.
Now of course, we didn't move ten studs because our part still has a mass to it.
And this was also a one time force that was also being pulled back down by gravity.
But if we were to imagine that there was no gravity in the game, there was no friction and I were to
set the assembly linear velocity to ten, my part would be moving ten studs per second in the y axis
or in the positive y direction, because this value actually represents the direction of the force based
on the global axes.
So if I were to apply a positive force on the y axis, it's always going to be up.
It doesn't matter what the orientation of the part is.
Now, setting the assembly linear velocity directly may result in unwanted behavior, because maybe
you want parts that have more mass to move less, while you want to have parts that have little mass
to move more.
Well, if you were to set the assembly linear velocity and always set it to the same value of, let's
say ten in the positive y axis, no matter what the mass of the part is, it's always going to move
the same amount.
So in order to solve that, we can use a function called apply impulse to apply a force on our object.
And that will take into consideration the mass and let's say the friction, uh, that is being applied
on our object.
So I'll make a reference to my physics part in the workspace.
And I can apply an impulse.
And my impulse is going to be a vector 3.nu.
And we'll do let's say a value of ten on the y axis.
Now let me increase the density back to 0.7 so we can get our mass of 44.8.
And if I hit enter, what you're going to notice is that my part didn't move at all, because this was
a very small force that just couldn't stand up against this mass.
It basically didn't move my part at all.
Now, if I were to reduce the density all the way down to 0.01, we should see our part move a little
bit.
So if I hit enter, there we go.
Our part bounced up just a little bit because.
It's basically almost massless.
If I bring the density back to point seven and I apply a greater impulse, let's say an impulse of 500,
then now my part bounces a little bit.
But if I were to swap the density back to 0.01 and apply this impulse, you're going to see that my
part just shot straight up into the air, because it's basically massless.
And we applied a huge force onto that part.
So this function is great for when you need to just apply a one time force on an object in a particular
direction.
And if you need to take into account the mass of your object, if you want to be able to set the linear
velocity directly without having to worry about the mass of the object, maybe you always want it to
move in the same direction, the same amount.
Then you would set the assembly linear velocity property directly.
Now there's another property here called assembly angular velocity, which is basically the exact same
thing as the linear velocity.
But instead this is representing rotational velocity.
So if I want my part to apply a rotational force, let's say a positive rotational force around the
y axis, if I were to do like 100.
As you can see, my part spun a lot and then eventually that force went back down to zero due to friction.
I can also take into account the mass of the object when I'm applying a rotational force.
By using the apply.
I believe it is.
Is it angular?
Yeah.
Apply angular impulse property.
So if I need to apply a rotational force on my object, and I want to keep it consistent across multiple
different objects with different masses, you can set the property directly.
Otherwise, if you need to take into account the mass of your object, then you would want to use the
apply angular impulse function.
So I could apply an angular impulse here.
Let's say uh a value of ten on the x axis.
And if I were to do this it only moves a little bit because, um, we're basically fighting against
this jagged object.
It's not going to be very easy to rotate it.
So let me try maybe a value of 100.
Okay.
There we go.
We got it to flip.
And then if I were to increase the density to like a value of one, make it really heavy and then apply
this force.
As you can see it does absolutely nothing because this object is too heavy to rotate with this current
force that I'm applying.
But if I bump that up and make it a big value now, I'm able to actually spin my object.
And if I have that density, go back down to 0.01 and then apply this force.
My part is gone, because that was just way too much force to apply on such a light object.
All right, the next thing we're going to go ahead and take a look at is going to be a vector force,
which applies a constant force on an assembly.
So I need to add an attachment into my part.
This is going to be where the force is being applied.
And then I can go ahead and add a vector force.
And then I need to define what attachment I need to apply a force at.
Let me go ahead and actually set the force to zero first of all.
So that way it's not going to apply a force right away.
But now I have defined this vector force as applying a force at this attachment.
And currently it's going to apply a force relative to the orientation of my attachment.
So this force vector right here is going to be dependent on what way my attachment is facing.
If I want to instead have this force be applied based on the global axes of the world, then I can just
switch this relative to property to world.
And then let me go ahead and try to apply a force of, let's say, ten on the y axis.
If I do that, you're going to see my arrow appear and it's trying to apply a force of ten on the y
axis, and it's constantly applying this force.
But of course, because my object is too heavy, nothing is happening.
But if I decide to bump up this value a bit more, maybe to 100.
Nothing's going to happen yet.
Maybe I'll try a thousand.
Still nothing.
How about about 10,000?
Okay, there we go.
And now my object is starting to fly away.
And let me bring that value back down.
And eventually I had to get to a point where my force went beyond the force of gravity.
I think the force of gravity.
What is it?
Where can I find.
Okay, gravity is 196.2, so I should be able to overcome gravity when this force here goes beyond that.
So if I set this to 192 or 193.
That actually still might not be enough because my object is too heavy.
So let me try reducing the density.
Okay.
Yeah, there it goes.
A little bit too much force.
Let me bring that back down to zero.
Come back.
But what you should be noticing is that as I am applying this constant force to my objects, it is getting
faster and faster and faster because there's nothing stopping it.
It's constantly applying a force and that force is building upon each other.
All right.
So considering that the amount of force that we need to overcome gravity with is going to be equal to
the mass of the object multiplied by the gravity in our game, uh, we should take into account our
mass, which is 0.64.
And we should multiply that by our gravity, which should give us a value that perfectly counteracts
gravity.
Which means if I were to move this part upwards, it should float in the air because it's fighting against
gravity perfectly.
So 196.2, which is the gravity in the game multiplied by 0.64, which is the mass of our object, will
yield us a value of 125.568, which should be the force required to not have this object fly away,
but be basically still wherever we put it, because it's perfectly balancing out against gravity.
So if we set this to 125.568.
As you can see, nothing is happening.
But as soon as I lift my object up.
Look at that.
Our part is unanchored, but it's floating.
And that's because this vector force is constantly applying a force that's perfectly counteracting gravity,
which means I could take another part like this and I could knock it into my object.
Let me see if I can change this.
Maybe to no, I can't change it to physical.
How could I, how could I knock this object into the other object here if I put.
Okay, there we go.
That kind of worked.
So as you can see now, our object is basically acting like there's no gravity in the game because I
can knock it around and it doesn't matter because this force inside of it is constantly working against
gravity.
This is basically now zero gravity, so any outside force I apply on it, it's going to completely disregard
gravity, which is really, really cool.
Now you keep hearing me use the terms assembly when we're talking about these different properties of
applying mass.
So let's go ahead and learn what an assembly is.
And I think the best way to learn what an assembly is, is by actually going to the official Roblox
documentation and reading what they have to say.
So inside of the Roblox documentation, they state that an assembly is one or more parts welded by a
rigid well constraint, or connected through movable joints like motor six DS.
You can group an assembly of parts in a model container to quickly organize the parts and related objects
as a single asset.
So basically, an assembly is just a bunch of parts that are connected together through welds or other
types of joints that basically act as one big body of objects.
And because you have the possibility of multiple parts being welded to other parts, you also have to
take into account the mass of those other objects as well when you're calculating physics.
So it says from a physics perspective, an assembly is considered a single rigid body, meaning no force
can push or pull the connected parts from each other, and they will move as a single unit.
All forces applied to a specific base part are applied to its assembly.
For instance, base part.
The apply impulse function applies impulse to the assembly at its assembly center of mass.
So if you had one single part not welded to anything else, then the center of mass would obviously
be within the center of the part.
But if you had maybe two parts that were, let's say, ten studs away from each other, welded to each
other, then the center of mass would obviously be within that distance between those two separate parts.
The Roblox documentation states that every assembly has a root part indicated by its assembly root part
property.
This is the part that doesn't move when the motor 60 transforms are updated, as well as the part used
to keep consistent physic replication and network ownership.
You cannot explicitly set the root part, but the following factors affect probability from highest
to lowest.
So the Roblox game engine automatically picks what the root part of an assembly is going to be, and
it does it in this order.
An anchor part will always be assigned as the root part, which makes sense.
Parts with massless set to false take precedent.
Higher root priority values take precedent, and then finally precedence based on the part size with
multipliers for parts with specific names.
So basically parts that have higher masses are going to likely be the parts set as the root part of
the assembly.
Back inside of studio.
If we currently look at the assembly section, you will see the assembly center of mass, which is going
to be the central position of my object, which is why this value also matches the position of my object
and also matches the origin of my object.
And then it also gives the assembly root part.
Now, since this is only one single part, obviously the assembly root part is the part itself.
But let's say I were to duplicate this part.
And I were to call this my physics part number two.
And let's say I made this one super heavy.
Let's increase the density to like ten.
So now I have a mass of 640.
And then let's go ahead and weld.
This part to my other part.
And now this is my assembly of two parts.
And if you take a look at my second part and we were to look at the assembly route part, obviously
now the new assembly route part is going to be my second physics part, because it is much heavier.
And you can also see the total mass of the entire assembly, which includes the mass of this part and
the mass of this part added together.
Now, if I were to add an attachment inside of my first physics part, and then let's say I added another
vector force, and I wanted to start applying forces relative to the world.
And let's go ahead and assign it this attachment.
As you can see, nothing is happening.
And that's because the amount of force I'm applying is not enough to overcome the amount of friction
with the ground due to the weight of this assembly.
So let's actually bump this up a bit more.
How about 10,000?
No.
Doesn't want to work.
Is it still too heavy?
Okay, then how about we do a hundred thousand?
Okay, there we go.
Oh, no.
Come back.
All right.
That was obviously way too much force.
And it was going in that direction we defined in the world.
So let's actually let's swap this relative to the attachment.
So that way when it starts applying the force um, once the force becomes greater enough, this should
start spinning in a circle because it's no longer going to apply the force based on the axes of the
world.
So let's actually try increasing okay.
There we go.
See, now my part is spinning, uh, faster and faster.
I'm.
This is not good.
Let me let me decrease that force.
Okay, there we go.
It's slowed down.
But as you can see, it started spinning in a circle because we're applying the force relative to the
attachment.
And that's going to be based on the orientation of our attachment.
So as we're applying a force our part is obviously going to start rotating because this one's lighter
and this is the heavier part.
It's going to rotate around this part.
And it's going to keep building up force and more force and more force until eventually it spins so
fast that it'll probably let's actually see how fast we can get it to spin.
So this is applying constant force and it's going to get faster and faster and faster until eventually
we might make some kind of particle accelerator or a nuclear bomb or something.
I don't know, but it's going to keep getting faster and faster, faster.
Um, let's actually make it really fast.
Let's apply more force.
How about more force?
And eventually, at this point, we'll get to, uh, a point of no return and we might break the physics
engine.
Hopefully this thing will calm down.
But I don't think it wants to come down.
Uh oh.
But we should basically be noticing is that, of course, it's applying the force relative to the attachment.
And since our second part over here is the bigger, heavier and badder part out of this assembly, that
force is being applied, uh, basically, uh, currently where the attachment is now, we can actually
change where this force is going to be applied if we tick apply at center of mass.
So instead of applying the force at where this attachment is and to demonstrate that, let's move this
detachment way far out like over there because we have apply at center of mass enabled, it's going
to apply the force wherever the center of mass is for this assembly.
And that means if we were to increase the value to like 25,000, actually that's not great enough.
Let's try 30,000.
Nope.
How about 40,000?
50,000.
Okay, there we go.
As you can see, it's no longer going to rotate because it's applying the force at the center of mass
of this assembly.
Pretty cool.
So definitely one of the very useful features of a vector force is because it applies a constant force.
You can manipulate gravity for individual players without having to manipulate the gravity for the entire
workspace or other physics in your game.
For example, if I want to have my player to have reduced gravity and only this particular player,
I can add a vector force to their root part and assign it to some kind of attachment that I've placed
at the center of the root part.
And then I have applied a force or a constant force of 2000 relative to the world.
So it's going to be always upwards that force.
And now when I go and jump, as you can see, it's acting like I'm in a place that has very low gravity.
And then, of course, if I wanted to have zero gravity in the game, then I would need to simply refer
to the total assembly mass and then multiply that according to the gravity in the game, and then set
that value inside of the vector force to basically have no gravity for my player.
The last instance that we're going to take a look at here is going to be the linear velocity, which
applies a constant velocity on an object regardless of its mass.
So instead of needing to apply a constant force, if you need to apply a constant velocity and you want
an assembly to always move at the same constant speed, then this is going to be a useful constraint
for that.
So let me add an attachment into my physics part.
Let me set the attachment.
Right there and then.
Now I can go ahead and define a vector velocity here.
Currently it's set relative to the world.
And then maybe I want my part to always move one stud every single second in the x direction.
So if I apply that force.
Currently nothing is working because there is force limits enabled.
But if I disable that, as you can see, it's going to start moving my object in that direction.
It doesn't care about any physics or anything because we don't have force limits enabled.
And now my object is always going to move one stud every single second.
And of course I can increase the speed to two studs, and then I can increase it to three studs.
And it's going to always constantly apply that force to try and move that direction that we have defined,
which is positive.
Two in the X direction.
And as you can see, it even lifted up the entire mass just to just to go in that particular direction.
Now, an interesting thing about this constraint is if I were to set the vector velocity to zero, and
I have this enabled with no force limits, you can basically now think of this part as anchor.
You can't move it because I've explicitly defined the velocity for this object to always be zero.
So that means even if I were to raise it into the air.
I think I broke the well, actually, no, it's still working.
If you notice, my object is not, uh, actually, it is moving.
It is very slowly moving.
Let me let me move it up a little bit more.
So if I were to do that and then let's say I did that.
Okay, you can basically see that my object is stuck in the air because I've explicitly defined the
vector velocity to be zero.
Now that doesn't affect the angular velocity.
As you can see, it's still kind of rotating around, uh, the point at which this vector velocity is
being applied.
But since I want the vector velocity to be zero, my part is basically now stuck in the air, even though
it's unanchored.
And then maybe I could be like, okay, you know what?
I want to apply a constant velocity upwards, or I want to have a constant velocity and on my object
will always move positive one studs upwards every single second, regardless of even if I change the
mass of this object.
So if I want to make this even heavier, as you can see, it doesn't do anything, it's still moving
at that same velocity if I.
All right.
Actually, I think that's the limit.
Can I make it any higher.
No.
Okay.
So even though the density of my object is 100 and the mass is 6400, it's still moving up at the same
speed.
And even if I were to set the density all the way to 0.01.
Still nothing happens because it is applying a constant force.
It doesn't care about the mass or friction in the game.
There is one last thing I would like to go over in this lecture, which is network ownership.
There were some additional properties that I did not go over in those other constraints.
If you want to learn more about them, there will be articles linked to this lecture that you can go
ahead and take a look at and mess around with those constraint instances a little bit more.
But on the topic of network ownership, I think this is very important to understand.
And network ownership is basically this idea that something has to calculate the physics for unanchored
parts.
Because these two parts are unanchored, they're going to have physics such as gravity and the like
acting upon it.
And in order for the game or the server that is hosting the game to save resources, it will outsource
that computation to any players that are nearby to unanchored parts.
So what I'm going to do is I'm going to launch a one player server and show you exactly how this network
ownership works.
So here I have my view on the client.
And then here I have my view on the server.
And right now by default, because these two unanchored parts are close to my player, my player has
automatically gained network ownership over them, which means my computer is handling the physics calculation
for these parts, and I can replicate that information to the server.
And the server replicates that information back to all the other clients in the game.
Now, this means that if I were to try to move these parts, actually they might be a little bit too
heavy for me to move.
Let me reduce the mass for these objects, okay?
I've reduced the mass for this particular assembly.
And as you can see as I move this object, I'm actually calculating the physics for that on my, uh,
my computer, which is why me interacting with this particular assembly is actually really smooth.
It's because I'm handling the physics and I'm giving that information to the server.
And in the server view, the server also gets to see that I am moving these objects around.
Now, an issue with network ownership or a vulnerability is because I have control over the physics
of this part on my client.
That means there is really nothing stopping me from manipulating the position or the forces being acted
on these parts.
So as an example, what I'm going to do is I'm going to open up the explorer window.
And let me go ahead and select, let's say this part here.
And let me just start moving it with the move tool.
Actually, it's not working, is it?
Because it might be because they're welded.
Okay, so it's a little broken on my client side, but I am moving.
I believe this should be the, uh, part that has.
Okay.
Yeah.
So because this is the, I guess, root part for this assembly, that's why I'm moving.
The other part wasn't working because this is not the root part for the assembly.
This is.
But as I start moving it, what you'll notice is that the server is also seeing those changes of me
moving this part.
I have control over where this part is positioned, or I even have control over the rotation for this
part as well.
So if I start rotating it, you're going to notice that those changes also replicate to the server.
And that's because I have network ownership over this part.
If I want to be able to manually set the network ownership of a part, that's easy to do, there's a
function for that.
So what I'm going to do is in the workspace, I'm going to get my physics part number two, and there's
a function called set network owner.
And to have the network ownership be given to the server and the server alone, I need to pass nothing
or basically nil.
And once I do that and I hit enter.
Now the physics for this part is going to be handled by the server and not my client, which means,
as you can see, I'm no longer able to rotate it and replicate those changes to the server, even if
I were to move this part around.
So let me pull out the move tool and start moving it.
And as you can see, this is not working.
It's being weird on my client, but you can see that the position is not updating on the server at all.
And it's also going to be a little bit wacky because as I move this object, I mean, obviously it's
bugged on my view, but you'll notice that this the physics for this part is not exactly responsive.
And that's because I'm not calculating the physics for it on the client.
The server is so it's being a little bit unresponsive and it's being a little bit slow.
And this kind of sucks.
So this is also the reason as to why even our character models, uh, we have a network ownership over
them, which is why they're really responsive.
If I move them around, I'm actually calculating all the physics for my character model on my client
side, and I'm replicating that information to the server, which means if I were to actually refer
to my character model.
So this is player one and I were to get the character or actually the humanoid root part, I believe.
Yeah.
Let me get the humanoid root part and let me set the network owner to the server.
Once I do that, I have lost control over the physics calculation for my character.
And as I start, oh gosh, it is extremely delayed and unresponsive.
So right now I'm pressing W and it took about a second for it to respond to my input.
And if I were to press spacebar, as you can see, it's really slow.
My player is lagging around.
And that's because I don't have network ownership over my character.
This really sucks.
Of course, I am able to set the network ownership back to my player.
I just need to pass it a player instance so I could do game dot players that player one and update the
network owner for my humanoid report.
And now everything's smooth again, because I have network ownership over the physics of my character
model, I can also set the network ownership to be automatic, again using a function called set network
ownership auto.
So if I do that, then the network ownership for my character is now automatic, which will still be
set to my computer because it's my character model.
But as for like these parts in the workspace, I could do workspace dot physics part two and set the
network ownership back to automatic.
So now it should have alleviated the control over the physics of that part from the server, and it
should have given it to my player because my player is like right next to it.
So now if I start interacting with it, you can see how much more smooth and responsive it is.
You can see that the physics is working just fine.
But if I were to set network ownership back to the server.
Or set network owner, I believe set network, set network owner back to the server and then try interacting
again.
You can see it's really buggy and glitchy and it doesn't work that well.
So network ownership is a really crucial idea to understand when you're making anything in your games
relating to physics, for example, vehicles in your game, the driver of the vehicle should have network
ownership over it, because if it doesn't, you'll likely end up with laggy, unresponsive, and kind
of crappy vehicles that aren't responding to your input that well.
Like if you had the physics solely be calculated by the server, then your vehicles might not even work
at all.
Now, I'm not an expert on physics, but just by learning and experimenting with the assembly linear
velocity of parts, messing around with linear velocities and vector forces, and understanding the
concept of network ownership allows you to really make whatever kind of strange and wacky physics related
type stuff you want in your game, maybe like a Ferris wheel.
Or you could make like a moving platform, or add zero gravity for specific players in your game and
stuff like that.
So if you're interested in learning more about these different instances and how you can use them to
manipulate physics in your game, all the documentation for them will be linked in this lecture, as
well as documentation for a network ownership.
Other than that, I hope you enjoyed this lecture and I will see you next time.